local Entity = class("Entity")
local SkillMove = require("gameLogic.fightSkill.show.SkillMove")
local Attributes = require("gameLogic.fightEntity.Attributes")
local AttributeConst = require("const.AttributeConst")
local AnimConst = require("const.AnimConst")
local GameUtils = require("utils.GameUtils")
local Vector3 = require("utils.Vector3")

function Entity:ctor()
    self._isDone = false
    self._isDie = false
    self._isPause = false
    self._standing = nil
    self._fightManager = nil
    self._name = ""
    self._showName = ""
    self._element = 0
    self._stance = {row = 1, col = 1}
    self._attr = Attributes.new()
    self._fakeAttr = {}
    self._skillList = {}
end

function Entity:setElement(element)
    self._element = element
end

function Entity:getElement()
    return self._element
end

function Entity:addFakeAttr(id, value)
    local v = self._fakeAttr[id] or 0
    self._fakeAttr[id] = v + value
end

function Entity:getFakeAttr()
    return self._fakeAttr
end

function Entity:setPause(pause)
    self._isPause = pause
end

function Entity:setShowName(name)
    self._showName = name
end

function Entity:getShowName()
    return self._showName
end

function Entity:setStance(row, col)
    self._stance = {row = row, col = col}
end

function Entity:getStance()
    return self._stance
end

function Entity:setManager(manager)
    self._fightManager = manager
end

function Entity:getManager()
    return self._fightManager
end

function Entity:setStanding(standing)
    printDebug("设置zhanwei" .. standing)
    self._standing = standing
end

function Entity:getStanding()
    return self._standing
end

function Entity:setAttr(attr)
    self._attr = attr
end

function Entity:getAttr()
    local attrs = self._attr:getContent()
    local clone = Attributes.new()
    for k, value in pairs(attrs) do
        local realValue = value
        if self._fakeAttr[k] then
            realValue = value + self._fakeAttr[k]
        end
        clone:setAttrValue(k, realValue)
    end
    return clone
end

function Entity:isDone()
    return self._isDone
end

function Entity:setDone(done)
    self._isDone = done
end

function Entity:setName(name)
    self._name = name
end

function Entity:getName()
    return self._name
end

function Entity:addSkill(skill)
    skill:setEntity(self)
    table.insert(self._skillList, skill)
end

function Entity:setSkills(skills)
    self._skillList = skills
end

function Entity:getSkills()
    return self._skillList
end

function Entity:setBloodUI(ui)
    self._bloodUI = ui
    self:_updateBlood()
end

function Entity:getBloodUI()
    return self._bloodUI
end

function Entity:getRoot()
    return self.transform:Find("root")
end

function Entity:start()
    self._animator = self.gameObject:GetComponent(typeof(Unity.Animator))
    self._render = self.gameObject:GetComponentInChildren(typeof(Unity.Renderer))
end

function Entity:update()
    if self._playDieing then
        local Length = self._render.materials.Length
        self._dieDt = self._dieDt + G_Time.deltaTime * 0.25
        self._dieDt = self._dieDt
        for i = 0, Length - 1 do
            self._render.materials[i]:SetFloat("_DissolveThreshold", self._dieDt)
        end
        if self._dieDt >= 1 then
            G_SignalManager:dispatch(SignalConst.EVENT_FIGHT_ENTITY_DIE)
            self.gameObject:SetActive(false)
            self._playDieing = false
        end
    end
end

function Entity:tick()
    if self:isDone() or self._fightManager:isFightEnd() then
        return
    end
    if self._isPause then
        return
    end
    if self._isDie then
        self:setDone(true)
        return
    end
    self:_tick()
end

function Entity:_tick()
end

function Entity:isDie()
    return self._isDie
end

function Entity:_playDie()
    local material = G_ResourceManager:loadMaterial("DissolveMat")
    local Length = self._render.materials.Length
    local array = {}
    for i = 1, Length do
        array[i] = material
        local tex = self._render.materials[i - 1]:GetTexture("_MainTex")
        material:SetTexture("_MainTex", tex)
    end
    self._render.materials = array
    self._playDieing = true
    self._dieDt = 0
end

function Entity:beAttack(value)
    local blood = self._attr:getAttrValue(AttributeConst.BLOOD)
    blood = blood - value
    self._attr:setAttrValue(AttributeConst.BLOOD, blood)
    if blood <= 0 then
        blood = 0
        self:_goDie()
    else
        self:triggerAnim(AnimConst.BeAttack)
    end
    self:_updateBlood()
end

function Entity:_checkDie()
    local blood = self._attr:getAttrValue(AttributeConst.BLOOD)
    if blood <= 0 then
        blood = 0
        self:_goDie()
    end
end

function Entity:subAttrValue(id, value)
    local blood = self._attr:getAttrValue(id)
    blood = blood - value
    self._attr:setAttrValue(id, blood)
    if id == AttributeConst.BLOOD then
        self:_checkDie()
        self:_updateBlood()
    end
end

function Entity:_goDie()
    self._isDie = true
    self:triggerAnim(AnimConst.DieTrigger)
    local sequence = DOTween.Sequence()
    local dieTime = GameUtils.getAnimationLength(self._animator, AnimConst.CLIP_DIE)
    sequence:AppendInterval(dieTime * 0.5)
    sequence:AppendCallback(
        function()
            self:_playDie()
        end
    )
end

function Entity:_updateBlood()
    if not self._bloodUI then
        return
    end
    local blood = self._attr:getAttrValue(AttributeConst.BLOOD)
    local initBlood = self._attr:getAttrValue(AttributeConst.INIT_BLOOD)
    self._bloodUI:setValue(blood / initBlood)
    printDebug(self._showName .. " 更新血量 当前：" .. blood .. " 最大：" .. initBlood)
end

function Entity:reset()
    self._isDone = false
end

function Entity:setAnimBoolean(name, flag)
    self._animator:SetBool(name, flag)
end

function Entity:getAnimator()
    return self._animator
end

function Entity:getCurAnimationLength()
    local info = self._animator:GetCurrentAnimatorStateInfo(0)
    return info.length
end

function Entity:triggerAnim(name)
    self._animator:SetTrigger(name)
end

function Entity:onDestroy()
end

return Entity
